#ifndef TEXT_INCLUDED
#define TEXT_INCLUDED

#include "fmt.h"

#define T Text_T

// Cannot modify string pointed by str, except that through Text_* functions or you create Text_T instance by yourself or returned by Text_box.
typedef struct T {
    int len;
    const char *str;
} T;

extern const T Text_cset;
extern const T Text_ascii;
extern const T Text_ucase;
extern const T Text_lcase;
extern const T Text_digits;
extern const T Text_null;

typedef struct Text_save_T* Text_save_T;

T     Text_put(const char *str);
char* Text_get(char *str, int size, T s);
T     Text_box(const char *str, int len);

T Text_sub(T s, int i, int j);
T Text_cat(T s1, T s2);
T Text_dup(T s, int n);
T Text_reverse(T s);
T Text_map(T s, const T *from, const T *to);

int Text_pos(T s, int i);
int Text_cmp(T s1, T s2);

// 假设 Text_save 返回 h ，Text_restore 会恢复缓冲区到 h 然后销毁后续分配的空间 .
Text_save_T Text_save();
void        Text_restore(Text_save_T *save);

int Text_chr(T s, int i, int j, int c);
int Text_rchr(T s, int i, int j, int c);
int Text_upto(T s, int i, int j, T set);
int Text_rupto(T s, int i, int j, T set);
int Text_find(T s, int i, int j, T str);
int Text_rfind(T s, int i, int j, T str);

int Text_any(T s, int i, T set);
int Text_many(T s, int i, int j, T set);
int Text_rmany(T s, int i, int j, T set);
int Text_match(T s, int i, int j, T str);
int Text_rmatch(T s, int i, int j, T str);

void Text_fmt(int code, va_list_box *box,
             int put(int c, void *cl), void *cl,
             unsigned char flags[256], int width, int precision);

#undef T

#endif

